﻿#define _CRT_SECURE_NO_WARNINGS

//#include <iostream>
//using namespace std;
//
//class A
//{
//
//};
//
//class B : public A
//{
//
//};
//
//class person
//{
//public:
//	virtual void buyTickets()
//	{
//		cout << "买票——全价" << endl;
//	}
//	virtual A* lineUp()
//	{
//		cout << "普通通道" << endl;
//		return nullptr;
//	}
//	void buyGoods()
//	{
//		cout << "买东西——原价" << endl;
//	}
//};
//
//class student : public person
//{
//public:
//	virtual void buyTickets()//与基类的buyTickets函数构成重写/覆盖
//	{
//		cout << "买票——半价" << endl;
//	}
//	virtual B* lineUp()//协变，与基类的lineUp函数构成重写/覆盖
//	{
//		cout << "学生通道" << endl;
//		return nullptr;
//	}
//	void buyGoods()//与基类的buyGoods函数构成隐藏
//	{
//		cout << "买东西——特价" << endl;
//	}
//};
//
//void func(person* tmp)
//{
//	tmp->buyTickets();
//	tmp->lineUp();
//	tmp->buyGoods();
//}
//
//int main()
//{
//	person p;
//	student s;
//	func(&p);
//	func(&s);
//	return 0;
//}


//#include <iostream>
//using namespace std;
//
////抽象类，无法实例化出对象
//class animal
//{
//public:
//	//纯虚函数可以实现也可以不实现，实现：
//	virtual void talk() const = 0 
//	{
//		cout << "不知道" << endl;
//	}
//
//	//不实现
//	//virtual void talk() = 0;
//
//	virtual void eat()const
//	{
//		cout << "吃好吃的" << endl;
//	}
//};
//
////继承抽象类，但凡有一个纯虚函数没有被重写，子类任然是抽象类
//class duck : public animal
//{
//public :
//	virtual void eat()const
//	{
//		cout << "吃小鱼" << endl;
//	}
//};
//
////继承抽象类，重写了基类的纯虚函数，所以子类不是抽象类
//class pig : public animal
//{
//public:
//	virtual void talk() const
//	{
//		cout << "哼唧哼唧" << endl;
//	}
//};
//
//void func(const animal& tmp)
//{
//	tmp.talk();
//}
//
//int main()
//{
//	pig p;
//	func(p);
//	return 0;
//}

#include <iostream>
using namespace std;

class animal
{
public:
	virtual void talk() const
	{
		cout << "阿巴阿巴" << endl;
	}
	
	//如果我们不想让派⽣类重写这个虚函数，那么可以⽤final去修饰
	virtual void eat()const final
	{
		cout << "吃好吃的" << endl;
	}
};

class totoro : public animal
{
public:
	//C++11提供了override，可以帮助用户检测是否重写
	virtual void talk() const override
	{
		cout << "多多洛" << endl;
	}
	
	//无法重写基类eat函数
	/*virtual void eat()const
	{
		cout << "吃小鱼小虾" << endl;
	}*/
};

void func(const animal& tmp)
{
	tmp.talk();
	tmp.eat();
}

int main()
{
	animal a;
	totoro t;
	func(a);
	func(t);
	return 0;
}